<?php

namespace App\Http\Controllers\Api;

use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;

// 文档
class DocumentController extends Controller
{
    // 目录
    private $dir;
    // 不生成文档的文件
    private $remove = [
        "ApiController.php",
        "DocumentController.php"
    ];
    // 页面展示的数据
    private $data = [];

    // 文档列表
    public function document()
    {
        // 目录
        $this->dir();
        // 文件列表
        $this->file();
        // 数据解析
        $this->data();

        return view('api.document.document', [
            'data' => $this->data
        ]);
    }

    // 获取文档目录目录
    private function dir()
    {
        $this->dir = app_path() . '/Http/Controllers/Api/';
    }

    // 文档文件
    private function file()
    {
        $data = scandir($this->dir);
        $file = [];
        foreach ($data as $key => $value) {
            if ($value != '.' && $value != '..' && ! in_array($value, $this->remove)) {
                $file[] = $value;
            }
        }
        $this->file = $file;
    }

    // 文件解析
    private function data()
    {
        $data = [];
        foreach ($this->file as $value) {
            $file = $this->dir . $value;
            $file = file_get_contents($file);
            $this->block($file);
        }
    }

    // 文件区块匹配
    private  function block($file)
    {
        preg_match_all("/\/\*\*(.*?)\*\//is", $file, $html);
        if ($html[1]) {
            foreach ($html[1] as $value) {
                $this->analyze($value); // 区块解析
            }
        }
    }

    // 区块解析
    private function analyze($html)
    {
        // 参数初始化
        $data = [
            'url' => '', // 接口信息
            'method' => '', // 方法
            'name' => '', // 接口名
            'param' => [], // 请求参数
            'response' => [], // 返回信息
            'field' => [], // 返回参数
            'returnjson' => [], // 返回示例 json
            'returnstring' => [] // 返回示例字符串
        ];

        $array = explode(PHP_EOL, $html);
        if (empty($array)) {
            return false;
        }
        foreach ($array as $v) {
            // url
            if (preg_match("/\s+\*\s@url\s+(.*)/is", $v, $temp)) {
                $data['url'] = trim($temp[1]);
            }
            // method
            if (preg_match("/\s+\*\s@method\s+(.*)/is", $v, $temp)) {
                $data['method'] = trim($temp[1]);
            }
            // name
            if (preg_match("/\s+\*\s@name\s+(.*)/is", $v, $temp)) {
                $data['name'] = trim($temp[1]);
            }
            // param
            if (preg_match("/\s+\*\s@param\s+(.*)/is", $v, $temp)) {
                $temp = $this->analyze_param(trim($temp[1]));
                if ($temp) {
                    $data['param'][] = $temp;
                }
            }
            // response
            if (preg_match("/\s+\*\s@response\s+(.*)/is", $v, $temp)) {
                $temp = $this->analyze_response_field(trim($temp[1]));
                if ($temp) {
                    $data['response'][] = $temp;
                }
            }
            // field
            if (preg_match("/\s+\*\s@field\s+(.*)/is", $v, $temp)) {
                $temp = $this->analyze_response_field(trim($temp[1]));  // 与 response 格式相同
                if ($temp) {
                    $data['field'][] = $temp;
                }
            }
            // returnjson
            if (preg_match("/\s+\*\s@returnjson\s+(.*)/is", $v, $temp)) {
                $temp = $this->analyze_returnjson(trim($temp[1]));  // json 格式化
                if ($temp) {
                    $data['returnjson'][] = $temp;
                }
            }
            // returnstring
            if (preg_match("/\s+\*\s@returnstring\s+(.*)/is", $v, $temp)) {
                $temp = trim($temp[1]);
                if ($temp) {
                    $data['returnstring'][] = $temp;
                }
            }
        }

        // 必备参数
        if ($data['url'] && $data['method'] && $data['name'] && $data['param'] && $data['field'] && ($data['returnjson'] | $data['returnstring'])) {
            $this->data[] = $data;
        }
    }

    // 请求参数解析
    private function analyze_param($data)
    {
        $array = [
            'type' => '',// 类型
            'param' => '', // 参数
            'pass' => 'R',// 是否必传
            'bewrite' => '', // 描述
        ];

        // 必传
        if(strpos($data, 'R|')) {
            $temp = explode('R|', $data);
            $array['pass'] = 'R';
        }
        // 非必传
        if(strpos($data, 'O|')) {
            $temp = explode('O|', $data);
            $array['pass'] = 'O';
        }
        if (empty($temp)) { // 未匹配到字符串
            return false;
        }
        // 切割前后字符串处理
        $array['bewrite'] = $temp[1];

        $temp = trim(preg_replace("/\s(?=\s)/","\\1",$temp[0]));  // 多个空格合并为一个
        $temp = explode(" ", $temp);
        if (count($temp) != 2) {
            return false;
        }
        $array['type'] = $temp[0];
        $array['param'] = $temp[1];

        return $array;
    }

    // 返回信息解析
    private function analyze_response_field($data)
    {
        $array = [
            'type' => '',// 类型
            'param' => '', // 参数
            'bewrite' => '', // 描述
        ];
        $temp = trim(preg_replace("/\s(?=\s)/","\\1",$data));  // 多个空格合并为一个
        $temp = explode(" ", $temp);
        if (count($temp) < 3) { // 参数数量不正确
            return false;
        }
        $array['type'] = $temp[0]; // type 赋值
        $array['param'] = $temp[1]; // param 赋值

        $strpos =  strpos($data, $temp[1]) + mb_strlen($temp[1], 'UTF-8'); // 第二个参数最后一次出现的位置
        $array['bewrite'] = trim(mb_substr($data, $strpos)); // 备注赋值

        return $array;
    }

    /* Json数据格式化 
    * @param  Mixed  $data   数据 
    * @param  String $indent 缩进字符，默认4个空格 
    * @return JSON 
    */
    private function analyze_returnjson($data, $indent = null)
    {
        // 是否为正常的json格式
        json_decode($data);
        if (json_last_error() != 0) {
            return false;
        }

        // json encode  
        // $data = json_encode($data, JSON_UNESCAPED_UNICODE);
        // 将urlencode的内容进行urldecode  
        $data = urldecode($data);
        // 缩进处理  
        $ret = '';
        $pos = 0;
        $length = strlen($data);
        $indent = isset($indent) ? $indent : '    ';
        $newline = "\n";
        $prevchar = '';
        $outofquotes = true;
        for ($i = 0; $i <= $length; $i++) {
            $char = substr($data, $i, 1);
            if ($char == '"' && $prevchar != '\\') {
                $outofquotes = !$outofquotes;
            } elseif (($char == '}' || $char == ']') && $outofquotes) {
                $ret .= $newline;
                $pos--;
                for ($j = 0; $j < $pos; $j++) {
                    $ret .= $indent;
                }
            }
            $ret .= $char;
            if (($char == ',' || $char == '{' || $char == '[') && $outofquotes) {
                $ret .= $newline;
                if ($char == '{' || $char == '[') {
                    $pos++;
                }
                for ($j = 0; $j < $pos; $j++) {
                    $ret .= $indent;
                }
            }
            $prevchar = $char;
        }
        return $ret;
    }
}

/**
* @url  /api/info/article
* @method GET
* @name 获取文章列表
* @param string categoryIds       R| 类别id 多个用逗号分割　类别可是学校类型和知识类别
* @param string or          R| 多个类别是或关系 默认是与关系
* @param string permission          R| 什么级别的会员可看
* @param string lazy  R| 是否懒加载 是只返回id 值0,1
* @param string tag R| 标签
* @param integer page R| 请求页面 0 
* @param integer pageSize R| 页面大小 20 
* @param integer sort         O| 排序
* @param integer desc O| 是否倒序
* @response string    code   消息 代 码   
* @response string    msg   消息 说 明   
* @response json    data   返回  数据 格式  
* @field int problem_id 问题id
* @field int problem_id 问题id
* @field int problem_id 问题id
* @field int problem_id 问题id
* @field int problem_id 问题id
* @field int problem_id 问题id
* @returnjson {"status":1,"msg":"请求成功","data":[{"name":"心意收入","funName":"Income\/getMindLists","number":180},{"name":"赏收入","funName":"Income\/getTipLists","number":25},{"name":"转诊收入","funName":"Income\/getRemoteConsultationLists","number":0},{"name":"提现记录","funName":"Wallet\/recordLists","number":205.02},{"name":"提现记录","funName":"http:\/\/101.200.221.231:11115/apk/%E5%AD%97%E4%BD%93(1).html","number":205.02}]}
* @returnstring 
*/